using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using umbraco.BasePages;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.property;
using umbraco.cms.businesslogic.propertytype;
using umbraco.cms.businesslogic.web;
using umbraco.interfaces;
using umbraco.uicontrols;
using Content=umbraco.cms.businesslogic.Content;

namespace umbraco.controls
{
    /// <summary>
    /// Summary description for ContentControl.
    /// </summary>
    public class ContentControl : TabView
    {
        private Content _content;
        private ArrayList _dataFields = new ArrayList();
        private UmbracoEnsuredPage prntpage;
        public event EventHandler SaveAndPublish;
        public event EventHandler SaveToPublish;
        public event EventHandler Save;
        private publishModes CanPublish = publishModes.NoPublish;
        public TabPage tpProp;
        public bool DoesPublish = false;
        private Hashtable inTab = new Hashtable();
        public TextBox NameTxt = new TextBox();
        private static string _UmbracoPath = GlobalSettings.Path;
        public Pane PropertiesPane = new Pane();

        // Error messages
        private string _errorMessage = "";

        public string ErrorMessage
        {
            set { _errorMessage = value; }
        }

        protected void standardSaveAndPublishHandler(object sender, EventArgs e)
        {
        }

        public ContentControl(Content c, publishModes CanPublish, string Id)

        {
            ID = Id;
            this.CanPublish = CanPublish;
            _content = c;

            Width = 350;
            Height = 350;
            SaveAndPublish += new EventHandler(standardSaveAndPublishHandler);
            Save += new EventHandler(standardSaveAndPublishHandler);
            prntpage = (UmbracoEnsuredPage) Page;

            foreach (ContentType.TabI t in _content.ContentType.getVirtualTabs)
            {
                TabPage tp = NewTabPage(t.Caption);
                addSaveAndPublishButtons(ref tp);

                tp.Style.Add("text-align", "center");


                // Iterate through the property types and add them to the tab
                foreach (PropertyType pt in t.PropertyTypes)
                {
                    // table.Rows.Add(addControl(_content.getProperty(editPropertyType.Alias), tp));
                    addControlNew(_content.getProperty(pt), tp, t.Caption);
                    inTab.Add(pt.Id.ToString(), true);
                }
            }


            // Add property pane
            tpProp = NewTabPage(ui.Text("general", "properties", null));
            addSaveAndPublishButtons(ref tpProp);
            tpProp.Controls.Add(
                new LiteralControl("<div id=\"errorPane_" + tpProp.ClientID +
                                   "\" style=\"display: none; text-align: left; color: red;width: 100%; border: 1px solid red; background-color: #FCDEDE\"><div><b>There were errors - data has not been saved!</b><br/></div></div>"));
        }


        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            // Add extras for the property tabpage. .

            NameTxt.ID = "NameTxt";
            if (!Page.IsPostBack)
            {
                NameTxt.Text = _content.Text;
            }

            PropertiesPane.addProperty(ui.Text("general", "name", null), NameTxt);

            Literal ltt = new Literal();
            ltt.Text = _content.User.Name;
            PropertiesPane.addProperty(ui.Text("content", "createBy", null), ltt);

            ltt = new Literal();
            ltt.Text = _content.CreateDateTime.ToString();
            PropertiesPane.addProperty(ui.Text("content", "createDate", null), ltt);

            ltt = new Literal();
            ltt.Text = _content.Id.ToString();
            PropertiesPane.addProperty("Id", ltt);

            tpProp.Controls.AddAt(0, PropertiesPane);
            tpProp.Style.Add("text-align", "center");
            //tpProp.Style.Add("padding", "10px");
        }

        protected override void OnLoad(EventArgs e)
        {
            foreach (Property p in _content.getProperties)
            {
                if (inTab[p.PropertyType.Id.ToString()] == null)
                    addControlNew(p, tpProp, ui.Text("general", "properties", null));
            }
            base.OnLoad(e);
        }


        private void saveClick(object Sender, ImageClickEventArgs e)
        {
            foreach (IDataEditor df in _dataFields)
            {
                df.Save();
            }
            _content.Text = NameTxt.Text;
            Save(this, new EventArgs());
        }

        private void savePublish(object Sender, ImageClickEventArgs e)
        {
            DoesPublish = true;
            saveClick(Sender, e);
            SaveAndPublish(this, new EventArgs());
        }

        private void saveToPublish(object Sender, ImageClickEventArgs e)
        {
            saveClick(Sender, e);
            SaveToPublish(this, new EventArgs());
        }

        private void addSaveAndPublishButtons(ref TabPage tp)
        {
            MenuImageButton menuSave = tp.Menu.NewImageButton();
            menuSave.ID = tp.ID + "_save";
            menuSave.ImageUrl = _UmbracoPath + "/images/editor/save.gif";
            menuSave.Click += new ImageClickEventHandler(saveClick);
            menuSave.OnClickCommand = "invokeSaveHandlers();";
            menuSave.AltText = ui.Text("buttons", "save", null);
            if (CanPublish == publishModes.Publish)
            {
                MenuImageButton menuPublish = tp.Menu.NewImageButton();
                menuPublish.ID = tp.ID + "_publish";
                menuPublish.ImageUrl = _UmbracoPath + "/images/editor/saveAndPublish.gif";
                menuPublish.OnClickCommand = "invokeSaveHandlers();";
                menuPublish.Click += new ImageClickEventHandler(savePublish);
                menuPublish.AltText = ui.Text("buttons", "saveAndPublish", null);
            }
            else if (CanPublish == publishModes.SendToPublish)
            {
                MenuImageButton menuToPublish = tp.Menu.NewImageButton();
                menuToPublish.ID = tp.ID + "_topublish";
                menuToPublish.ImageUrl = _UmbracoPath + "/images/editor/saveToPublish.gif";
                menuToPublish.OnClickCommand = "invokeSaveHandlers();";
                menuToPublish.Click += new ImageClickEventHandler(saveToPublish);
                menuToPublish.AltText = ui.Text("buttons", "saveToPublish", null);
            }
        }


        private void addControlNew(Property p, TabPage tp, string Caption)
        {
            IDataType dt = p.PropertyType.DataTypeDefinition.DataType;
            dt.DataEditor.Editor.ID = p.PropertyType.Alias;
            dt.Data.PropertyId = p.Id;

            // check for element additions
            IMenuElement menuElement = dt.DataEditor.Editor as IMenuElement;
            if (menuElement != null)
            {
                // add separator
                tp.Menu.InsertSplitter();

                // add the element
                tp.Menu.NewElement(menuElement.ElementName, menuElement.ElementIdPreFix + p.Id.ToString(),
                                   menuElement.ElementClass, menuElement.ExtraMenuWidth);
            }

            // check for buttons
            IDataFieldWithButtons df1 = dt.DataEditor.Editor as IDataFieldWithButtons;
            if (df1 != null)
            {
                // df1.Alias = p.PropertyType.Alias;
                /*
				// df1.Version = _content.Version;
				editDataType.Data.PropertyId = p.Id;
				*/
                ((Control) df1).ID = p.PropertyType.Alias;


                if (df1.MenuIcons.Length > 0)
                    tp.Menu.InsertSplitter();


                // Add buttons
                int c = 0;
                bool atEditHtml = false;
                bool atSplitter = false;
                foreach (object o in df1.MenuIcons)
                {
                    try
                    {
                        MenuIconI m = (MenuIconI) o;
                        MenuIconI mi = tp.Menu.NewIcon();
                        mi.ImageURL = m.ImageURL;
                        mi.OnClickCommand = m.OnClickCommand;
                        mi.AltText = m.AltText;
                        mi.ID = tp.ID + "_" + m.ID;

                        if (m.ID == "html")
                            atEditHtml = true;
                        else
                            atEditHtml = false;

                        atSplitter = false;
                    }
                    catch
                    {
                        tp.Menu.InsertSplitter();
                        atSplitter = true;
                    }

                    // Testing custom styles in editor
                    if (atSplitter && atEditHtml && dt.DataEditor.TreatAsRichTextEditor)
                    {
                        DropDownList ddl = tp.Menu.NewDropDownList();

                        ddl.Style.Add("margin-bottom", "5px");
                        ddl.Items.Add(ui.Text("buttons", "styleChoose", null));
                        ddl.ID = tp.ID + "_editorStyle";
                        if (StyleSheet.GetAll().Length > 0)
                        {
                            foreach (StyleSheet s in StyleSheet.GetAll())
                            {
                                foreach (StylesheetProperty sp in s.Properties)
                                {
                                    ddl.Items.Add(new ListItem(sp.Text, sp.Alias));
                                }
                            }
                        }
                        ddl.Attributes.Add("onChange", "addStyle(this, '" + p.PropertyType.Alias + "');");
                        atEditHtml = false;
                    }
                    c++;
                }
            }

            // fieldData.Alias = p.PropertyType.Alias;
            // ((Control) fieldData).ID = p.PropertyType.Alias;
            // fieldData.Text = p.Value.ToString();

            _dataFields.Add(dt.DataEditor.Editor);


            Pane pp = new Pane();
            Control holder = new Control();
            holder.Controls.Add(dt.DataEditor.Editor);
            if (p.PropertyType.DataTypeDefinition.DataType.DataEditor.ShowLabel)
            {
                string caption = p.PropertyType.Name;
                if (p.PropertyType.Description != null && p.PropertyType.Description != String.Empty)
                    switch (UmbracoSettings.PropertyContextHelpOption)
                    {
                        case "icon":
                            caption += " <img src=\"" + GlobalSettings.Path + "/images/help.png\" class=\"umbPropertyContextHelp\" alt=\"" + p.PropertyType.Description + "\" />";
                            break;
                        case "text":
                            caption += "<br /><small>" + p.PropertyType.Description + "</small>";
                            break;
                    }
                pp.addProperty(caption, holder);
            }
            else
                pp.addProperty(holder);

            // Validation
            if (p.PropertyType.Mandatory)
            {
                try
                {
                    RequiredFieldValidator rq = new RequiredFieldValidator();
                    rq.ControlToValidate = dt.DataEditor.Editor.ID;
                    Control component = dt.DataEditor.Editor; // holder.FindControl(rq.ControlToValidate);
                    ValidationPropertyAttribute attribute =
                        (ValidationPropertyAttribute)
                        TypeDescriptor.GetAttributes(component)[typeof (ValidationPropertyAttribute)];
                    PropertyDescriptor pd = null;
                    if (attribute != null)
                    {
                        pd = TypeDescriptor.GetProperties(component, (Attribute[]) null)[attribute.Name];
                    }
                    if (pd != null)
                    {
                        rq.EnableClientScript = false;
                        rq.Display = ValidatorDisplay.Dynamic;
                        string[] errorVars = {p.PropertyType.Name, Caption};
                        rq.ErrorMessage = ui.Text("errorHandling", "errorMandatory", errorVars, null) + "<br/>";
                        holder.Controls.AddAt(0, rq);
                    }
                }
                catch (Exception valE)
                {
                    HttpContext.Current.Trace.Warn("contentControl",
                                                   "EditorControl (" + dt.DataTypeName + ") does not support validation",
                                                   valE);
                }
            }

            // RegExp Validation
            if (p.PropertyType.ValidationRegExp != "")
            {
                try
                {
                    RegularExpressionValidator rv = new RegularExpressionValidator();
                    rv.ControlToValidate = dt.DataEditor.Editor.ID;

                    Control component = dt.DataEditor.Editor; // holder.FindControl(rq.ControlToValidate);
                    ValidationPropertyAttribute attribute =
                        (ValidationPropertyAttribute)
                        TypeDescriptor.GetAttributes(component)[typeof (ValidationPropertyAttribute)];
                    PropertyDescriptor pd = null;
                    if (attribute != null)
                    {
                        pd = TypeDescriptor.GetProperties(component, (Attribute[]) null)[attribute.Name];
                    }
                    if (pd != null)
                    {
                        rv.ValidationExpression = p.PropertyType.ValidationRegExp;
                        rv.EnableClientScript = false;
                        rv.Display = ValidatorDisplay.Dynamic;
                        string[] errorVars = {p.PropertyType.Name, Caption};
                        rv.ErrorMessage = ui.Text("errorHandling", "errorRegExp", errorVars, null) + "<br/>";
                        holder.Controls.AddAt(0, rv);
                    }
                }
                catch (Exception valE)
                {
                    HttpContext.Current.Trace.Warn("contentControl",
                                                   "EditorControl (" + dt.DataTypeName + ") does not support validation",
                                                   valE);
                }
            }

            // This is once again a nasty nasty hack to fix gui when rendering wysiwygeditor
            if (dt.DataEditor.TreatAsRichTextEditor)
            {
                tp.Controls.Add(dt.DataEditor.Editor);
            }
            else
            {
                Panel ph = new Panel();
                ph.Attributes.Add("style", "padding: 0px 0px 0px 0px");
                ph.Controls.Add(pp);

                tp.Controls.Add(ph);
            }
        }

        public enum publishModes
        {
            Publish,
            SendToPublish,
            NoPublish
        }
    }
}